import { PingComponent } from "../../../../Model/Client/Demo/Ping/PingComponent";
import { ObjectSystemAttribute, FriendOf } from "../../../../../Decorator/Decorator";
import { AwakeSystem } from "../../../../../Core/Module/EventSystem/IAwakeSystem";
import { DestroySystem } from "../../../../../Core/Module/EventSystem/IDestroySystem";
import { Session } from "../../../../Model/Share/Module/Message/Session";
import { TimeHelper } from "../../../../../Core/Module/Time/TimeHelper";
import { C2G_Ping, G2C_Ping } from "../../../../Model/Generate/Share/Message/OuterMessage_C_10001";
import { TimeInfo } from "../../../../../Core/Module/Time/TimeInfo";
import { TimerComponent } from "../../../../../Core/Module/Timer/TimerComponent";
import { Log } from "../../../../../Core/Module/Log/Log";

@FriendOf(PingComponent)
@ObjectSystemAttribute()
export class PingComponentAwakeSystem extends AwakeSystem<PingComponent> {

    Awake(self: PingComponent): void {
        PingComponentAwakeSystem.PingAsync(self).then();
    }

    private static async PingAsync(self: PingComponent) {
        const session = self.GetParent<Session>();
        const instanceId = self.InstanceId;

        while (true) {
            if (self.InstanceId != instanceId) {
                return;
            }
            const time1 = TimeHelper.ClientNow();
            try {
                const response = await session.Call(new C2G_Ping()) as G2C_Ping;
                if (self.InstanceId != instanceId) {
                    return;
                }
                const time2 = TimeHelper.ClientNow();
                self.Ping = time2 - time1;
                // TimeInfo.Instance.ServerMinusClientTime = Number(response.Time + BigInt((time2 - time1) / 2 - time2));
                TimeInfo.Instance.ServerMinusClientTime = Number(response.Time);
                await TimerComponent.Instance.WaitAsync(2000);
            } catch (e) {
                Log.Info(`ping error: ${self.Id} ${e}`);
            }
        }
    }

}

@FriendOf(PingComponent)
@ObjectSystemAttribute()
export class PingComponentDestroySystem extends DestroySystem<PingComponent> {

    Destroy(self: PingComponent): void {
        self.Ping = Number.MAX_VALUE;
    }

}